package com.example.ktapplication.base

import android.annotation.SuppressLint
import android.content.Context
import android.content.res.Resources
import android.graphics.ColorMatrix
import android.graphics.ColorMatrixColorFilter
import android.graphics.Paint
import android.os.Build
import android.os.Bundle
import android.os.Looper
import android.transition.Fade
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.annotation.IntegerRes
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.viewbinding.ViewBinding
import com.example.ktapplication.dialog.DialogLoading
import com.example.ktapplication.utils.SpUtils
import com.example.ktapplication.utils.ToastUtil
import com.example.ktapplication.utils.event.Event
import com.example.ktapplication.utils.event.EventBusUtil
import com.google.firebase.crashlytics.buildtools.reloc.com.google.common.eventbus.Subscribe
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import me.jessyan.autosize.AutoSizeCompat
import me.jessyan.autosize.AutoSizeConfig

abstract class BaseActivity<T : ViewBinding> : AppCompatActivity() {

    lateinit var binding: T

    /**
     * 获取当前显示的fragment
     */
    private val currentVisibleFragment: Fragment?
        get() {
            return supportFragmentManager.fragments.firstOrNull { it.isVisible }
        }

    override fun attachBaseContext(newBase: Context?) {
        super.attachBaseContext(newBase?.run {
//            changeLanguage()
            this
        })
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (SpUtils.getInstance().getValue("GRAY",false)){
            grayApp()
        }
        binding = getViewBind()

        if (showWhitAnima()) {
            window.enterTransition = Fade()
            window.exitTransition = Fade()
        }

        binding.root?.let {
            if (it is ViewGroup) {
                setContentView(it)
            }
        }

        if (isRegisterEvent()) {
            EventBusUtil.eventBus.register(this)
        }

        if (needKeepOn()) {
            window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        }

        onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                onPhoneBackPressed()
            }
        })

        onDate(savedInstanceState)
        onViewBing()

    }

    /**
     * 启动是否带有动画效果
     */
    open fun showWhitAnima(): Boolean {
        return false
    }

    /**
     * 显示fragment
     */
    @SuppressLint("ResourceType")
    fun showFragment(fragment: Fragment, @IntegerRes id: Int) {
        if (fragment == currentVisibleFragment) return
        val beginTransaction = supportFragmentManager.beginTransaction()
        //    beginTransaction.setCustomAnimations(R.anim.fragment_enter_anim, R.anim.fragment_exit_anim)
        if (!fragment.isAdded || fragment.isDetached) {
            beginTransaction.add(id, fragment)
        }
        currentVisibleFragment?.let {
            beginTransaction.hide(it)
        }
        beginTransaction.show(fragment)
        beginTransaction.commit()
    }

    override fun onDestroy() {
        super.onDestroy()
        try {
            if (isRegisterEvent()) {
                EventBusUtil.eventBus.unregister(this)
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 是否要屏幕常亮
     */
    open fun needKeepOn(): Boolean {
        return false
    }

    /**
     * 设置当前是否全屏
     */
    open fun setFullScreen(): Boolean {
        return false
    }


    /**
     * 返回界面ui
     */
    abstract fun getViewBind(): T

    /**
     * 是否注册eventbus事件
     */
    open fun isRegisterEvent(): Boolean {
        return false
    }

    /**
     * 数据获取
     */
    abstract fun onDate(savedInstanceState: Bundle?)

    /**
     * view控件绑定
     */
    abstract fun onViewBing()

    override fun onWindowFocusChanged(hasFocus: Boolean) {
        super.onWindowFocusChanged(hasFocus)
        if (setFullScreen()) {
            setFullScreen(true)
        }
    }

    fun setFullScreen(shouldFull: Boolean) {
        val decorView = window.decorView
        if (shouldFull) {
            window.setFlags(
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN
            )
            if (Build.VERSION.SDK_INT >= 28) {
                val lp = window.attributes
                lp.layoutInDisplayCutoutMode =
                    WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
                window.attributes = lp
            }
            var uiOptions =
                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
            uiOptions = uiOptions or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
            uiOptions = uiOptions or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            uiOptions = uiOptions or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            uiOptions = uiOptions or View.SYSTEM_UI_FLAG_FULLSCREEN
            decorView.systemUiVisibility = uiOptions
        } else {
            var uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            decorView.systemUiVisibility = uiOptions
            window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
            if (Build.VERSION.SDK_INT >= 28) {
                val lp = window.attributes
                lp.layoutInDisplayCutoutMode =
                    WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
                window.attributes = lp
            }
        }
    }

    /**
     * 手机滑动返回或者手动返回定义按钮返回事件捕捉
     */
    open fun onPhoneBackPressed() {
        finish()
    }

    /**
     * 处理横竖屏之后比例变了导致的问题
     */
    override fun getResources(): Resources {
        if (Looper.myLooper() == Looper.getMainLooper()) {          //这里变换需要在主线程进行操作，不是主线程不进行操作
            val width = AutoSizeConfig.getInstance().screenWidth.toFloat()
            val height = AutoSizeConfig.getInstance().screenHeight.toFloat()
            val sizeInDp = (if (width > height) width / height else height / width) * 375f
            AutoSizeCompat.autoConvertDensity(super.getResources(), sizeInDp, width > height)
        }
        return super.getResources()
    }

    /**
     * binding是否已经初始化
     */
    fun viewBingIsInit(): Boolean {
        return ::binding.isInitialized
    }

    private val mDialogLoading by lazy {
        DialogLoading.instance
    }

    private var showDialog: Boolean = false

    fun showDialog(context: String, tag: String) {
        showDialog = true
        lifecycleScope.launch(Dispatchers.Main) {
            mDialogLoading.setTip(context)
            mDialogLoading.show(supportFragmentManager, tag)
        }
    }

    fun dismissDialog() {
        if (showDialog) {
            lifecycleScope.launch(Dispatchers.Main) {
                mDialogLoading.dismiss()
            }
        }
    }

    fun showToast(msg: String) {
        ToastUtil.showToast(this, msg)
    }

    fun grayApp(){
        val paint = Paint()
        val colorMatrix = ColorMatrix()
        colorMatrix.setSaturation(0f)
        paint.colorFilter = ColorMatrixColorFilter(colorMatrix)
        window.decorView.setLayerType(View.LAYER_TYPE_HARDWARE, paint)
    }
}